#ifndef __PROCESS_H_
#define __PROCESS_H_
#include <types.h>
#include <pm.h>
#include <list.h>

/*===========定义进程表进程数量===========*/
#define NR_S_TASKS      2
#define NR_U_TASKS      0

/*===========定义 LDT 索引===========*/
#define SEG_CODE_LDT    0
#define SEG_DATA_LDT    1

/*===========定义 LDT 索引===========*/
#define EFLAGS_PSW    0x202
#define EFLAGS_SYS_PSW  0x1202
/**
 * @brief 进程状态
 * TASK_RUNNING : 可运行进程
 */
enum task_state {
    TASK_RUNNING,
    TASK_BLOCKED,
    TASK_STATES,
};
/**
 * @brief 
 * 
 */
#define task_convert(pnode) container_of(task_list, task_t, pnode)
#define running_list    ((struct list_head*)(&task_list_table[TASK_RUNNING]))
/*===========进程运行级别===========*/
enum task_priv {
    KERNEL_PRIV,
    USER_PRIV,
};


/*   进程切换保存的进程寄存器信息   */
struct thread_info {
    /*
     *==============特殊段寄存器=================
     */
    reg_t   gs;
    reg_t   fs;
    reg_t   es;
    reg_t   ds;
    /*
     *==============普通寄存器 pushad  popad 寄存器=================
     */
    reg_t   edi;
    reg_t   esi;
    reg_t   ebp;
    reg_t   kernel_esp;

    reg_t   ebx;
    reg_t   edx;
    reg_t   ecx;
    reg_t   eax;
    /*
     *==============call save的时候自动保存=================
     */
    reg_t   link;
    /*
     *==============中断自动压入的寄存器=================
     */
    reg_t   eip;
    reg_t   cs;
    reg_t   eflags;             // iret 只压三个

    reg_t   esp;
    reg_t   ss;
}__attribute__ ((packed));


/*   内核进程堆栈   */
union thread_union {
    struct thread_info thread_info;
    uint32_t stack[2048];
};

/**
 * @brief task_struct
 * 进程描述结构体
 */
struct task_struct {

    /*=====一个进程必须的信息===========*/
    struct thread_info thread_info;
    selector_t ldt_sel;                     /*   lldt 是将这个 sel 指向的全局描述符内容装载到 ldtr寄存器，用来指定 当前使用的 ldt 表   */
    struct seg_desc ldt[2];
    uint8_t dpl;
    /*=====自定义信息===========*/
    pid_t pid;
    struct list_head task_list;

    enum task_state state;
    
    enum task_priv priv;

}__attribute__ ((packed));

typedef struct task_struct task_t;

extern void _Low_RestoreTask(void);

#define run_task    _Low_RestoreTask()

int register_task(uint32_t func, uint8_t DPL);
void task_init(void);
void switch_to(void);
#endif